/*
 * Copyright 2023-2025, Haiku, Inc. All rights reserved.
 * Distributed under the terms of the MIT License.
 *
 * 龙芯3A6000 LIOINTC本地I/O中断控制器驱动
 * 参考Linux的drivers/irqchip/irq-loongson-liointc.c实现
 */

#ifndef _LOONGSON_LIOINTC_H
#define _LOONGSON_LIOINTC_H

#include <KernelExport.h>
#include <SupportDefs.h>

// LIOINTC寄存器定义
#define LOONGSON_LIOINTC_ISR       0x00    // 中断状态寄存器
#define LOONGSON_LIOINTC_IEN       0x04    // 中断使能寄存器
#define LOONGSON_LIOINTC_IOC       0x08    // 中断输出控制寄存器
#define LOONGSON_LIOINTC_MAP0      0x0c    // 中断映射寄存器0
#define LOONGSON_LIOINTC_MAP1      0x10    // 中断映射寄存器1
#define LOONGSON_LIOINTC_MAP2      0x14    // 中断映射寄存器2
#define LOONGSON_LIOINTC_MAP3      0x18    // 中断映射寄存器3

// LIOINTC配置常量
#define LOONGSON_LIOINTC_MAX_IRQS  32      // 最大中断数量
#define LOONGSON_LIOINTC_UART_IRQ  2       // UART中断号
#define LOONGSON_LIOINTC_HT_IRQ    3       // HyperTransport中断号
#define LOONGSON_LIOINTC_PCI_IRQ   4       // PCI中断号
#define LOONGSON_LIOINTC_IPI_IRQ   12      // IPI中断号
#define LOONGSON_LIOINTC_TIMER_IRQ 11      // 定时器中断号

// 中断优先级定义
#define LOONGSON_LIOINTC_PRIO_0    0       // 优先级0（最低）
#define LOONGSON_LIOINTC_PRIO_1    1       // 优先级1
#define LOONGSON_LIOINTC_PRIO_2    2       // 优先级2
#define LOONGSON_LIOINTC_PRIO_3    3       // 优先级3（最高）

// 中断控制器结构体
typedef struct {
    addr_t base_addr;                       // 寄存器基地址
    uint32 irq_base;                        // 中断基础编号
    uint32 num_irqs;                        // 中断数量
    uint32 irq_enable;                      // 中断使能状态
    uint32 irq_map[4];                      // 中断映射状态
} loongson_liointc;

// 函数声明
status_t loongson_liointc_init(addr_t base_addr, uint32 irq_base);
void loongson_liointc_uninit(void);

status_t loongson_liointc_enable_interrupt(uint32 irq);
status_t loongson_liointc_disable_interrupt(uint32 irq);
status_t loongson_liointc_configure_interrupt(uint32 irq, uint32 priority);

// 中断处理函数
int32 loongson_liointc_handle_interrupt(void *data);

// 处理器间中断(IPI)相关函数
status_t loongson_liointc_send_ipi(uint32 target_cpu);
status_t loongson_liointc_send_broadcast_ipi(void);

#endif // _LOONGSON_LIOINTC_H